﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _443_Server
{
	public class OutPackets
	{
		public Player Player { get; set; }
		public Stream InStream { get; set; }
		public Stream OutStream { get; set; }
		private int lastOffset;

		public OutPackets(Player p)
		{
			Player = p;
			InStream = p.InStream;
			OutStream = p.OutStream;
			lastOffset = 0;
		}

		public void CreatePacket(int id)
		{
			OutStream.WriteByte((byte)id);
		}

		public void CreatePacketByte(int id)
		{
			OutStream.WriteByte((byte)id);
			lastOffset = OutStream.BufferLocation;
			OutStream.BufferLocation++;
		}

		public void CreatePacketShort(int id)
		{
			OutStream.WriteByte((byte)id);
			lastOffset = OutStream.BufferLocation;
			OutStream.BufferLocation += 2;
		}

		public void EndPacketByte()
		{
			int length = OutStream.BufferLocation - lastOffset - 1;
			if (length > 255)
				throw new Exception("Packet size byte > 255");
			OutStream.Buffer[lastOffset] = (byte)length;
		}

		public void EndPacketShort()
		{
			int length = OutStream.BufferLocation - lastOffset - 2;
			if (length > 65535)
				throw new Exception("Packet size short > 65535");
			OutStream.Buffer[lastOffset] = (byte)(length >> 8);
			OutStream.Buffer[lastOffset + 1] = (byte)length;
		}

		public void SendMapRegion()
		{
			CreatePacketShort(121);
			OutStream.WriteWordLittleEndian((ushort)Player.Location.RegionX);
			OutStream.WriteWordLittleEndian((ushort)Player.Location.LocalY);
			OutStream.WriteWordLittleEndianA((ushort)Player.Location.LocalX);
			OutStream.WriteByteA((byte)Player.Location.H);

			for (int x = (Player.Location.RegionX - 6) / 8; x <= (Player.Location.RegionX + 6) / 8; x++)
			{
				for (int y = (Player.Location.RegionY - 6) / 8; y <= (Player.Location.RegionY + 6) / 8; y++)
				{
					int region = y + (x << 8);
					OutStream.WriteDWordMixedEndian(0);
					OutStream.WriteDWordMixedEndian(0);
					OutStream.WriteDWordMixedEndian(0);
					OutStream.WriteDWordMixedEndian(0);
					/*OutStream.WriteDWordMixedEndian(mapData[region][0]);
					OutStream.WriteDWordMixedEndian(mapData[region][1]);
					OutStream.WriteDWordMixedEndian(mapData[region][2]);
					OutStream.WriteDWordMixedEndian(mapData[region][3]);*/
				}
			}
			OutStream.WriteWordA((ushort)Player.Location.RegionY);
			EndPacketShort();
		}

		private int pingId = 0;
		public void SendPingPacket()
		{
			CreatePacketShort(204);
			OutStream.WriteDWord(pingId++);
			EndPacketShort();
		}

		public void ShowWelcomeScreen()
		{
			CreatePacket(221);
			OutStream.WriteWord(378);
			OutStream.WriteWordLittleEndianA(405);
		}

		public void SendAllTabs()
		{
			SendTab(0, 92); // Attack tab
			SendTab(1, 320); // Skill tab
			SendTab(2, 274); // Quest tab
			SendTab(3, 149); // Inventory tab
			SendTab(4, 387); // Equipment tab
			SendTab(5, 271); // Prayer tab
			SendTab(6, 192); // Magic tab
			SendTab(8, 131); // Friend tab
			SendTab(9, 148); // Ignore tab
			SendTab(10, 182); // Logout tab
			SendTab(11, 261); // Setting tab
			SendTab(12, 464); // Emote tab
			SendTab(13, 239); // Music tab
		}

		public void SendTab(int tab, int interfaceID)
		{
			CreatePacket(90);
			OutStream.WriteByte((byte)tab);
			OutStream.WriteWordA((ushort)interfaceID);
		}

		public void CloseAllInterfaces()
		{
			CreatePacket(178);
		}

		public void SendMessage(string s)
		{
			CreatePacketByte(157);
			OutStream.WriteString(s);
			EndPacketByte();
		}

		public void SetChatOptions(int publicChat, int privateChat, int trade)
		{
			CreatePacket(91);
			OutStream.WriteByte((byte)publicChat);
			OutStream.WriteByte((byte)privateChat);
			OutStream.WriteByte((byte)trade);
		}

		public void ShowInterface(int id)
		{
			CreatePacket(160);
			OutStream.WriteWordA((ushort)id);
		}

		public void ShowInterfaceWithSidebar(int parent, int child)
		{
			CreatePacket(146);
			OutStream.WriteWordLittleEndianA((ushort)parent);
			OutStream.WriteWord((ushort)child);
		}

		public void SetInterfaceText(int parent, int child, string text)
		{
			CreatePacketShort(180);
			OutStream.WriteDWordLittleEndian((parent << 16) | child);
			OutStream.WriteString(text);
			EndPacketShort();
		}
	}
}
